package com.ayf.payment.game.api.service.payment;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.dto.OrderAndMerchantDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.entity.Partition;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.service.payment.util.PackageHtmlPayementFormUtil;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.HttpPostUrl;
import com.ayf.payment.game.api.utils.JsonUtils;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wwl
 * @description:
 * @date 2020/5/18 17:37
 */
@Service
public class ZFYPaymentService extends IPaymentService {

    public static final String Version = "1.0";

    @Override
    public Map<String, Object> paymentUtil(Order order, Partition partition, String orderCreateStr, String traceId, String redirectUrl) {
        Map<String, Object> repMap = new HashMap<>();
        MerchantPaymentProductDTO merchantPaymentProductDTO = systemInitialization.productDTO(order.getPayTypeId());
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(merchantPaymentProductDTO.getcId());
        BigDecimal actualOrderAmt = getActualOrderAmt(order.getAmount(),paymentChannelDTO.getId(),partition.getMerchantId());
        String resultCode = orderCreate(order, orderCreateStr, traceId, redirectUrl,actualOrderAmt,merchantPaymentProductDTO,paymentChannelDTO);
        if (resultCode == null) {
            throw new NullSetException("下单失败，请稍后重试！");
        }
        if (resultCode.indexOf("payform") > 0) {
            order.setRandomAmt(BigDecimal.ZERO);
            order.setOrderNo("");
            order.setPayChannleName(paymentChannelDTO.getName());
            order.setPayChannleId(paymentChannelDTO.getId());
            order.setPayTypeId(merchantPaymentProductDTO.getProductId());
            order.setPayTypeName(merchantPaymentProductDTO.getProductName());
            order.setMerchantIncome(BigDecimal.ZERO);
            order.setPlatformIncome(BigDecimal.ZERO);
            order.setFee(BigDecimal.ZERO);
            order.setChannelIncome(BigDecimal.ZERO);
            orderMapper.insertSelective(order);
            repMap.put("code", "002");
            repMap.put("htmlMsg", resultCode);
        } else {
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        return repMap;
    }

    private String orderCreate(Order order, String orderCreateStr, String traceId, String redirectUrl,BigDecimal actualOrderAmt,MerchantPaymentProductDTO merchantPaymentProductDTO,PaymentChannelDTO paymentChannelDTO) {
        traceId = "支付云创建订单 ".concat(traceId);
        //商户编号
        String MerhantId = paymentChannelDTO.getAccountNumber();
        //测试商户密钥
        String KeyValue = paymentChannelDTO.getChannelKey();
        //交易请求地址
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        if (!AuthorizationURL.endsWith("/")) {
            AuthorizationURL = AuthorizationURL.concat("/");
        }
        AuthorizationURL = AuthorizationURL.concat("cashier/req");
        String returnUrl = paymentChannelDTO.getReturnUrl();
        if (!returnUrl.endsWith("/")) {
            returnUrl = returnUrl.concat("/");
        }
        String orderAmount = actualOrderAmt.setScale(2, BigDecimal.ROUND_DOWN).toString();
        //支付请求签名的原始串
        String Origin = Version + MerhantId + order.getMerchantOrderNo() +orderAmount + getPayCode(merchantPaymentProductDTO.getBusinessCode()) + returnUrl + "gameapip/v/zfy/pay/notify" + returnUrl + "gameapip/v/zfy/pay/returns" + redirectUrl + "";
        //MD5加密
        String signd = Md5Utils.encryption(Origin+"|" + KeyValue);
        Map<String, String> mapParam = new HashMap<String, String>();
        mapParam.put("Version", Version);                //版本号
        mapParam.put("Charset", "UTF-8");							//字符集编码选填
        mapParam.put("MerId", MerhantId);                    //商户号
        mapParam.put("TransNo", order.getMerchantOrderNo());                        //商户订单号
        mapParam.put("OrderAmount",orderAmount);                    //支付金额
        mapParam.put("PayChannel", getPayCode(merchantPaymentProductDTO.getBusinessCode()));                    //支付渠道
        mapParam.put("ProductName", "");
        mapParam.put("NotifyUrl", returnUrl + "gameapip/v/zfy/pay/notify");            //服务端通知发货地址
        mapParam.put("PostBackUrl", returnUrl + "gameapip/v/zfy/pay/returns");        //支付成功后客户端浏览器回调地址
        mapParam.put("Remark", redirectUrl);
        mapParam.put("InsCode", "");
        mapParam.put("Sign", signd);                            //签名串(重要)
        String payFormHmtl = PackageHtmlPayementFormUtil.packageHtmlPayementForm(mapParam,AuthorizationURL);
        LogPortal.info("{} 商户ID[{}] 商户订单号[{}] 请求报文[{}]",traceId,order.getMerchantId(),order.getMerchantOrderNo(),payFormHmtl);
        return payFormHmtl;
    }

    @Override
    public void queryPayOrder(OrderAndMerchantDTO dto, String traceId) {
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(dto.getPayChannleId());
        String KeyValue = paymentChannelDTO.getChannelKey();
        String resultCode = queryCreate(dto.getMerchantId(), dto.getMerchantOrderNo(), traceId,paymentChannelDTO);
        Map<String, String> map = JsonUtils.jsonToDo(resultCode, Map.class);
        if (map.isEmpty()) {
            LogPortal.error("支付云{} 执行查询订单返回参数为空", traceId);
            return;
        }
        String Version = map.get("Version");
        String Code = map.get("Code");
        String Msg = map.get("Msg");
        String MerId = map.get("MerId");
        String TransNo = map.get("TransNo");
        String OrderNo = map.get("OrderNo");
        String OrderAmount = map.get("OrderAmount");
        String TransAmount = map.get("TransAmount");
        String Status = map.get("Status");
        String TransTime = map.get("TransTime");
        String Remark = map.get("Remark");
        String Sign = map.get("Sign");
        if("1".equals(Status)){
            Msg="";
        }
        if (StringUtils.isEmpty(OrderNo)) {
            LogPortal.error("支付云{} 支付平台查询订单商户订单号{}数值为空，不进行后续操作", traceId, dto.getMerchantOrderNo());
            return;
        }
        Order order = orderService.selectByMerchantOrderNo(OrderNo);
        if (order == null) {
            LogPortal.error("支付云{} 查询订单号[{}]在我方系统查询不到", traceId, OrderNo);
            return;
        }
        String Origin = Version + Code + Msg + MerId + TransNo + OrderNo + OrderAmount + TransAmount + Status + TransTime + Remark;
        String signs = Md5Utils.encryption(Origin + "|" + KeyValue);

        if (null !=Sign & Sign.equals(signs)) {
            OrderStatus orderStatus = OrderStatus.PROCESSING;
            if ("1".equals(Status)) {
                orderStatus = OrderStatus.SUCCESS;
            }
            if (OrderStatus.PROCESSING.equals(order.getOrderStatus()) && !orderStatus.equals(OrderStatus.PROCESSING)) {
                order.setOrderNo(TransNo);
                order.setOrderStatus(orderStatus);
                order.setChannelRpsMsg(map.get("msg"));
                orderService.paymentOrder(order, new JSONObject());
                if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                    orderService.orderToGetWay(order);
                    wxSendMsgUtils.rechargeSuccess(order);
                }
            }
        }
    }

    private String queryCreate(Integer merchantId, String merchantOrderNo, String traceId,PaymentChannelDTO paymentChannelDTO) {
        //商户编号
        String MerId = paymentChannelDTO.getAccountNumber();
        //测试商户密钥
        String KeyValue = paymentChannelDTO.getChannelKey();
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();

        String Origin = Version + MerId + merchantOrderNo + traceId;
        String Sign = Md5Utils.encryption(Origin + "|" + KeyValue);
        Map<String, String> mapParam = new HashMap<String, String>();
        mapParam.put("Version", Version);                //版本号
        mapParam.put("Charset", "UTF-8");							//字符集编码选填
        mapParam.put("MerId", MerId);                    //商户号
        mapParam.put("TransNo", merchantOrderNo);                        //商户订单号
        mapParam.put("NonceStr", traceId);                    //支付金额
        mapParam.put("Sign", Sign);                    //支付渠道
        LogPortal.info("支付云{} 商户ID[{}] 商户订单号[{}] 查询订单请求参数[{}]", traceId, merchantId, merchantOrderNo, JsonUtils.strToJson(mapParam));
        String result = "";
        try {
            //请求上游接口
            result = HttpPostUrl.sendPost(AuthorizationURL + "/service/api/orderquery", mapParam, traceId);
            LogPortal.info("支付云{}查询订单 商户ID[{}] 商户订单号[{}] 返回参数[{}]", traceId, merchantId, merchantOrderNo, result);
        } catch (Exception e) {
            LogPortal.error("支付云{}查询订单 商户ID[{}] 商户订单号[{}] 支付渠道查询订单失败，发生了{}异常，错误描述:{}", e, traceId, merchantId, merchantOrderNo, e.getClass().getName(), e.getMessage());
        }
        return result;
    }

    private String getPayCode(String code) {
        if ("ALIPAY".equals(code)||"ANTCREDITPAY".equals(code)) {
            return "ALIPAY";
        } else if ("WECHAT".equals(code)) {
            return "WEIXIN";
        } else {
            throw new NullSetException("该通道不支持充值，请更换其他通道充值！");
        }
    }
}
